"""
文本格式化核心模块
提供各种文本格式化功能
"""

import re
import json
import xml.etree.ElementTree as ET
from typing import Optional, Dict, Any
from autopep8 import fix_code
import jsbeautifier


class TextFormatter:
    """文本格式化器"""
    
    def __init__(self):
        self.supported_languages = {
            'python': self._format_python,
            'javascript': self._format_javascript,
            'json': self.format_json,
            'xml': self.format_xml,
            'html': self._format_html,
            'css': self._format_css,
            'sql': self._format_sql
        }
    
    def format_case(self, text: str, case_type: str) -> str:
        """
        大小写转换
        
        Args:
            text: 输入文本
            case_type: 转换类型 ('upper', 'lower', 'title', 'camel', 'snake', 'kebab')
        
        Returns:
            转换后的文本
        """
        if not text:
            return text
            
        case_type = case_type.lower()
        
        if case_type == 'upper':
            return text.upper()
        elif case_type == 'lower':
            return text.lower()
        elif case_type == 'title':
            return text.title()
        elif case_type == 'camel':
            return self._to_camel_case(text)
        elif case_type == 'snake':
            return self._to_snake_case(text)
        elif case_type == 'kebab':
            return self._to_kebab_case(text)
        else:
            return text
    
    def _to_camel_case(self, text: str) -> str:
        """转换为驼峰命名"""
        words = re.findall(r'[a-zA-Z0-9]+', text)
        if not words:
            return text
        return words[0].lower() + ''.join(word.capitalize() for word in words[1:])
    
    def _to_snake_case(self, text: str) -> str:
        """转换为下划线命名"""
        text = re.sub(r'([a-z])([A-Z])', r'\1_\2', text)
        text = re.sub(r'[^a-zA-Z0-9_]', '_', text)
        return text.lower().strip('_')
    
    def _to_kebab_case(self, text: str) -> str:
        """转换为短横线命名"""
        text = re.sub(r'([a-z])([A-Z])', r'\1-\2', text)
        text = re.sub(r'[^a-zA-Z0-9-]', '-', text)
        return text.lower().strip('-')
    
    def remove_extra_spaces(self, text: str) -> str:
        """去除多余空格和换行"""
        # 去除行首行尾空格
        lines = [line.strip() for line in text.split('\n')]
        # 去除空行
        lines = [line for line in lines if line]
        # 合并多个空格为单个空格
        lines = [re.sub(r'\s+', ' ', line) for line in lines]
        return '\n'.join(lines)
    
    def add_indentation(self, text: str, spaces: int = 4) -> str:
        """添加缩进"""
        indent = ' ' * spaces
        lines = text.split('\n')
        return '\n'.join(indent + line if line.strip() else line for line in lines)
    
    def remove_indentation(self, text: str) -> str:
        """去除缩进"""
        lines = text.split('\n')
        return '\n'.join(line.lstrip() for line in lines)
    
    def format_json(self, text: str, indent: int = 2) -> str:
        """JSON格式化"""
        try:
            # 尝试解析JSON
            data = json.loads(text)
            return json.dumps(data, indent=indent, ensure_ascii=False)
        except json.JSONDecodeError:
            return text
    
    def minify_json(self, text: str) -> str:
        """JSON压缩"""
        try:
            data = json.loads(text)
            return json.dumps(data, separators=(',', ':'), ensure_ascii=False)
        except json.JSONDecodeError:
            return text
    
    def format_xml(self, text: str, indent: int = 2) -> str:
        """XML格式化"""
        try:
            root = ET.fromstring(text)
            return self._pretty_xml(root, indent)
        except ET.ParseError:
            return text
    
    def _pretty_xml(self, elem: ET.Element, indent: int = 2) -> str:
        """美化XML输出"""
        def _indent(elem, level=0):
            i = "\n" + level * " " * indent
            if len(elem):
                if not elem.text or not elem.text.strip():
                    elem.text = i + " " * indent
                if not elem.tail or not elem.tail.strip():
                    elem.tail = i
                for subelem in elem:
                    _indent(subelem, level + 1)
                if not elem.tail or not elem.tail.strip():
                    elem.tail = i
            else:
                if level and (not elem.tail or not elem.tail.strip()):
                    elem.tail = i
        
        _indent(elem)
        return ET.tostring(elem, encoding='unicode')
    
    def format_code(self, text: str, language: str) -> str:
        """代码格式化"""
        if language in self.supported_languages:
            return self.supported_languages[language](text)
        return text
    
    def _format_python(self, text: str) -> str:
        """Python代码格式化"""
        try:
            return fix_code(text, options={'aggressive': 1})
        except:
            return text
    
    def _format_javascript(self, text: str) -> str:
        """JavaScript代码格式化"""
        try:
            opts = jsbeautifier.default_options()
            opts.indent_size = 2
            return jsbeautifier.beautify(text, opts)
        except:
            return text
    
    def _format_html(self, text: str) -> str:
        """HTML格式化"""
        try:
            # 简单的HTML格式化
            text = re.sub(r'>\s*<', '>\n<', text)
            text = re.sub(r'\n\s*\n', '\n', text)
            return text
        except:
            return text
    
    def _format_css(self, text: str) -> str:
        """CSS格式化"""
        try:
            # 简单的CSS格式化
            text = re.sub(r';\s*', ';\n', text)
            text = re.sub(r'{\s*', ' {\n', text)
            text = re.sub(r'}\s*', '\n}\n', text)
            return text
        except:
            return text
    
    def _format_sql(self, text: str) -> str:
        """SQL格式化"""
        try:
            # 简单的SQL格式化
            keywords = ['SELECT', 'FROM', 'WHERE', 'AND', 'OR', 'ORDER BY', 'GROUP BY', 'HAVING', 'INSERT', 'UPDATE', 'DELETE']
            for keyword in keywords:
                text = re.sub(rf'\b{keyword}\b', f'\n{keyword}', text, flags=re.IGNORECASE)
            return text.strip()
        except:
            return text
    
    def align_text(self, text: str, alignment: str, width: int = 80) -> str:
        """文本对齐"""
        lines = text.split('\n')
        
        if alignment == 'center':
            return '\n'.join(line.center(width) for line in lines)
        elif alignment == 'right':
            return '\n'.join(line.rjust(width) for line in lines)
        elif alignment == 'left':
            return '\n'.join(line.ljust(width) for line in lines)
        else:
            return text
    
    def word_wrap(self, text: str, width: int = 80) -> str:
        """文本换行"""
        import textwrap
        return textwrap.fill(text, width=width)
    
    def format_date_time(self, text: str, format_type: str) -> str:
        """日期时间格式化"""
        from datetime import datetime
        
        try:
            # 尝试解析常见的日期格式
            common_formats = [
                '%Y-%m-%d %H:%M:%S',
                '%Y-%m-%d',
                '%d/%m/%Y',
                '%m/%d/%Y',
                '%Y%m%d',
                '%H:%M:%S'
            ]
            
            for fmt in common_formats:
                try:
                    dt = datetime.strptime(text.strip(), fmt)
                    if format_type == 'iso':
                        return dt.isoformat()
                    elif format_type == 'readable':
                        return dt.strftime('%Y年%m月%d日 %H:%M:%S')
                    elif format_type == 'short':
                        return dt.strftime('%Y-%m-%d')
                    else:
                        return dt.strftime(format_type)
                except ValueError:
                    continue
            
            return text
        except:
            return text 